Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

als-require

Package Overview
Dependencies
Maintainers
0
Versions
36
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

als-require

A utility for using CommonJS require in the browser and creating bundles.

  • 1.7.0
  • npm
  • Socket score

Version published
Weekly downloads
25
increased by150%
Maintainers
0
Weekly downloads
 
Created
Source

als-require

als-require is a lightweight utility that enables the importation and modification of CommonJS modules before execution in both browser and Node.js environments.

Capabilities of als-require:

  • Utilize CommonJS modules in the browser, complete with all dependencies and access to module functionalities.
  • Employ a unified context object across all modules.
  • Modify the code of each module before it is executed.
  • Build minified (optional) bundle for browser

Installation

To install als-require, use npm:

npm install als-require

Importing

Import in nodejs:

const Require = require('als-require')
const module = Require.getModule('./some/path')

Import in browser:

<script src="/node_modules/als-require/require.js"></script>
or
<script src="/node_modules/als-require/require.min.js"></script>

<script>
   Require.version = '1.0'; // optional - adding version when fetching files
   Require.cyclicDependencies = true // false by default
   Require.logger = console // console by default
   Require.getModule('./some/path')
   .then(module => {/* code */})

   // or 
   require('./some/path')
   .then(module => {/* code */})

</script>

Usage

als-require has two files for NodeJS and browser which has same structure and api. Each file includes Require class with folowing structure:

class Require {
   static getModule(path, context, contextName,modules) {}
   static _requireClass = null
   static cyclicDependencies = false // allow cyclic dependencies
   static logger = console // logger for logger.warn

   static contents = {}

   constructor(path) {
      this.contents = {}
      this.path = path
      this.fullPath
      this.contentReady = false
   }
   
   // returns promise in browser
   getContent() {}
   
   // returns result
   build(modules = {}, context = {}, contextName = 'context') {}
   
   // only in nodejs version. returns bundle
   bundle(options={}) {} 
   //default options = { context = {}, script = '', contextName = 'context', minified = true }
}

const require = Require.getModule // in browser

The structure above describes only properties and methods for usage, without additional properties and methods which used as private methods.

Arguments:

  • path (String): relative path to module for require
  • context (Object): shared object which will be available in all modules
  • contextName (String): Name for context variable (default context)

Here explanation what each method and property used for:

  • Require.getModule - quick way to get contents and build them in one step
    • returns new instance of Requires with ready contents, modules and result
    • The method is sync for NodeJS and async for browser
  • Require.contents - includes modules contents and their children list and used as cache
  • require.getContent() - used for reading module file's contents
    • Adding content to Require.contents and to require.contents
    • The browser version is async and NodeJS version is sync
  • require.build(modules,context,contextName) - builds all modules results
    • return main module result (export) after build
    • add to modules obejct all module's results after build
  • bundle - returns bundle inside (function() {})()
    • script - Additional script to execute after bundle created (default '')
      • script will get access to context, modules and result after creation, but before returning the result
    • context - The context for build in bundle (default empty object)
    • contextName - name for context variable (default 'context')
    • minified: minify the result (default true)

Node.Js

const Require = require('als-require')
const mod = new Require('./relative/path/to/module')
mod.getContent() // reading all modules
for(const path in mod.contents) {
   mod.contents[path] = mod.contents[path] // modify if needed
}
const context = {} // shared object for all modules empty object by default
const modules = {} // will include all module`s results {relativePath:moduleResult,...}
const result = mod.build(modules,context) // build the result

Browser

<script src="/node_modules/als-require/require.js"></script>
<script>
   const mod = new Require('./relative/path/to/module')
   const promise = mod.getContent() // fetching all modules
   promise.then(mod => {
      for(const path in mod.contents) {
         mod.contents[path] = mod.contents[path] // modify if needed
      }
      const modules={}, context = {}
      const result = mod.build(modules,context) // build the result
   })
</script>

Require node_modules packages and node modules

In case of path which not starts with ., Require will look for file in node_modules (by checking in package.json). If such package not found (for example require('fs')), result for this package will return null.

const somePackage = require('some-package');
const somePackage1 = require('./node_modules/some-package/index.js');
const fs = require('fs');

module.exports = {somePackage,somePackage1,fs}

In case above somePackage and somePackage1 should return the package, but fs, should return null.

Pay attention, using './node_modules/some-package/index.js' instead 'some-package', you save extra request/readFile for looking the filename.

Context Usage

The context object is a shared space accessible by all modules loaded by als-require. This allows modules to read and write shared data, enabling more interactive and dynamic module behaviors.

Make sure you are using the context for static value (like constants and common variables and functions) and not dynamic, cause it available to all require's results.

Bundle Method

The bundle method in als-require is designed to compile all the required modules into a single executable JavaScript bundle. This method is particularly useful for preparing code that needs to be executed in a browser environment where modules may not be natively supported or where a single script file is preferred for performance reasons.

Parameters

The bundle method accepts an options object that can be used to customize the behavior of the bundling process. Here are the available options:

  • context (Object): A shared object that will be available in all modules. This object can be used to pass state or utilities between modules.
    • The context may include functions, objects and more, the final context stringified with als-object-serializer
  • contextName (String): The name of the variable that will hold the context object within the bundled code. Defaults to 'context'.
  • script (String): Additional JavaScript code to be executed at the end of the bundle. This script can interact with the modules and the context.
  • minified (Boolean): Whether to minify the resulting bundle. Minification reduces the size of the bundle but can make debugging more difficult.

Mechanism

The bundle method operates by first gathering all the modules specified by their paths and dependencies, ensuring they are all loaded and resolved correctly. It then compiles these modules into a single JavaScript function, which includes code to build it. If minified is true, it applies a minification algorithm to compress the code.

The context object is serialized and injected into the bundle, allowing all modules to access shared data through the specified contextName. Finally, any additional script provided in the script option is appended to the end of the function, allowing for custom logic to be executed when the bundle is loaded.

Usage Examples

Basic Usage

Here's how you might create a simple bundle with some additional script:

const Require = require('als-require');
const path = './relative/path/to/module';
const mod = new Require(path);
mod.getContent();

const options = {
  script: 'console.log("Bundle executed",{modules,context,result});',
  context: { userId: 123 },
  contextName: 'appContext',
  minified: true
};

const bundleScript = mod.bundle(options);
console.log(bundleScript); // Outputs the bundled script
Server-Side Rendering (SSR)

You can use the bundle method in conjunction with server-side rendering to prepare a script that will rehydrate the server-rendered page in the client's browser:

const mod = new Require(path);
mod.getContent();

const serverRenderedContent = mod.build();

const clientBundle = mod.bundle({
  script: 'startApp(result,context);',
  context: serverRenderedContent,
  minified: false
});

const rawHtml = `
<!DOCTYPE html>
<html lang="en">
<head><title>App</title></head>
<body>${serverRenderedContent}</body>
<script>${clientBundle}</script>
</html>
`;

// Send rawHtml as the response to the client

In this example, serverRenderedContent might be HTML or other content generated by the server based on the modules, and clientBundle is a script that will effectively "take over" in the browser, allowing for a smooth transition from server-rendered to client-side dynamic content.

Advanced Scenarios

You can also use the bundle method to create different bundles based on runtime conditions, such as different user roles, feature flags, or experimental features. This allows for a highly customizable delivery of resources tailored to specific user experiences or testing scenarios.

Keywords

FAQs

Package last updated on 16 Nov 2024

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc